<!--  -->
<template>
    <div class="page-container">
        <div class="page-panel">
            <el-card class="left-card">
                <h2 class="section-title">Modbus</h2>
                <label class="label">报文数据 (十六进制)</label>
                <el-input type="textarea" rows="6" v-model="modbusInput" placeholder="请输入十六进制报文数据"></el-input>

                <label class="label">fromCard</label>
                <el-input type="text" v-model="fromCard" placeholder="请输入fromCard"></el-input>

                <label class="label">toCard</label>
                <el-input type="text" v-model="toCard" placeholder="请输入fromCard"></el-input>

                <label class="label">时间</label>
                <el-date-picker v-model="modbusTm" type="datetime" format="yyyy-MM-dd HH:mm:ss"
                    value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期时间">
                </el-date-picker>

                <div class="control-panel">
                    <el-button type="primary" plain @click="formatMessage(0)">格式化报文</el-button>
                    <!-- <el-button type="primary" plain @click="calculateCRC(0)">计算CRC</el-button> -->
                    <el-button type="primary" plain @click="validateMessage(0)">验证报文</el-button>
                    <el-button type="primary" plain @click="submitMessage(0)">上传报文</el-button>
                    <el-button type="primary" plain @click="clearMessage(0)">清空数据</el-button>
                </div>
            </el-card>
            <el-card class="right-card">
                <h2 class="section-title">PS+Modbus</h2>
                <label class="label">报文数据 (十六进制)</label>
                <el-input type="textarea" rows="6" v-model="psModbusInput" placeholder="请输入十六进制报文数据"></el-input>

                <label class="label">时间</label>
                <el-date-picker v-model="psModbusTm" type="datetime" format="yyyy-MM-dd HH:mm:ss"
                    value-format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期时间">
                </el-date-picker>

                <div class="control-panel">
                    <el-button type="primary" plain @click="formatMessage(1)">格式化报文</el-button>
                    <el-button type="primary" plain @click="validateMessage(1)">验证报文</el-button>
                    <el-button type="primary" plain @click="submitMessage(1)">上传报文</el-button>
                    <el-button type="primary" plain @click="clearMessage(1)">清空数据</el-button>
                </div>
            </el-card>
        </div>
    </div>
</template>

<script>
// CRC16 查找表
const auchCRCHi = [
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
    0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
    0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
    0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
    0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
    0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
    0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
];

const auchCRCLo = [
    0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
    0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
    0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
    0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
    0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
    0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
    0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
    0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
    0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
    0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
    0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
    0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
    0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
    0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
    0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
    0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
    0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
    0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
    0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
    0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
    0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
    0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
    0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
    0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
    0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
    0x43, 0x83, 0x41, 0x81, 0x80, 0x40
];
export default {
    components: {},
    data() {
        return {
            modbusInput: '65 2C 00 3E 00 03 F4 DF 00 00 02 C1 00 00 00 00 00 04 00 00 04 D2 00 00 06 D8 00 00 0F 61 00 00 1E 0C 00 00 00 00 00 00 00 00 00 00 00 00 05 72 00 00 6D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5A BD',
            fromCard: '',
            toCard: '',
            modbusTm: null,
            psModbusInput: '12 34 56 00 48 80 01 0B 15 03 39 29 77 30 0B 00 00 00 00 00 10 65 2C 00 3E 00 02 BC 31 00 00 02 EF 00 00 00 00 00 00 00 00 06 D2 00 00 04 58 00 00 22 BB 00 00 1E 40 00 00 00 00 00 00 00 00 00 00 00 00 05 6B 00 00 6D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 5E A2 FF',
            psModbusTm: null
        }
    },
    computed: {},
    created() { },
    mounted() { },
    methods: {
        formatMessage(type) {
            var hexMessage = ""
            if (type === 0) {
                hexMessage = this.modbusInput
            } else {
                hexMessage = this.psModbusInput
            }
            // 验证十六进制格式
            if (!/^[0-9A-F]*$/.test(hexMessage)) {
                this.$message({
                    message: '错误：输入包含非十六进制字符',
                    type: 'warning'
                });
                return;
            }

            // 格式化显示（每两个字符一组）
            const formatted = hexMessage.match(/.{1,2}/g)?.join(' ') || '';
            if (type === 0) {
                this.modbusInput = formatted
            } else {
                this.psModbusInput = formatted
            }

        },
        calculateCRC(type) { },
        validateMessage(type) {
            var hexMessage = ""
            if (type === 0) {
                hexMessage = this.modbusInput
            } else {
                hexMessage = this.psModbusInput.substring(42, this.psModbusInput.length - 2)
            }
            hexMessage = hexMessage.replace(/\s/g, "");
            debugger

            var hexMessage_ = parseInt(hexMessage.substring(4, 8), 16)
            if (hexMessage.length / 2 - 6 != hexMessage_) {
                this.$message({
                    message: `报文长度不匹配：当前${hexMessage - 6}字节，目标${hexMessage_}字节`,
                    type: 'warning'
                });
                return;
            }
            var hexData = hexMessage.substring(0, hexMessage.length - 4);
            var crc = this.calculateCRC16(hexData)
            const crcHex = crc.toString(16).padStart(4, '0').toUpperCase();
            const crcHex_ = hexMessage.substring(hexMessage.length - 4, hexMessage.length);
            if (crcHex != crcHex_) {
                this.$message({
                    message: `CRC校验失败：当前${crcHex}，目标${crcHex_}`,
                    type: 'warning'
                });
            }
            this.$message({
                message: '验证通过',
                type: 'success'
            });


        },
        // CRC16 计算函数
        calculateCRC16(hexData) {
            const bytes = this.hexStringToBytes(hexData);
            let uchCRCHi = 0xFF;
            let uchCRCLo = 0xFF;

            for (let i = 0; i < bytes.length; i++) {
                const uIndex = (uchCRCHi ^ bytes[i]) & 0xFF;
                uchCRCHi = (uchCRCLo ^ auchCRCHi[uIndex]) & 0xFF;
                uchCRCLo = auchCRCLo[uIndex];
            }

            return (uchCRCHi << 8) | uchCRCLo;
        },
        // 十六进制字符串转字节数组
        hexStringToBytes(hexString) {
            if (hexString.length % 2 !== 0) {
                throw new Error('十六进制字符串长度必须为偶数');
            }

            const bytes = [];
            for (let i = 0; i < hexString.length; i += 2) {
                const byte = parseInt(hexString.substr(i, 2), 16);
                if (isNaN(byte)) {
                    throw new Error('无效的十六进制字符');
                }
                bytes.push(byte);
            }
            return bytes;
        },
        submitMessage(type) {
            if (type === 0) {
                if (this.fromCard == '' || this.toCard == '' || this.modbusTm == null) {
                    this.$message.error('请填写卡号时间完整的信息');
                    return;
                }
                this.$request({
                    url: '/beidouApi/beidou/modbus',
                    method: 'get',
                    params: {
                        fromCard: this.fromCard,
                        toCard: this.toCard,
                        time: this.modbusTm,
                        content: this.modbusInput.replace(/\s/g, "")
                    }
                }).then((res) => {
                    if (res.code === 200) {
                        this.$message({
                            message: '补数完成',
                            type: 'success'
                        });
                    }
                })

            } else {
                if (this.psModbusTm == null) {
                    this.$message.error('请填写时间完整的信息');
                    return;
                }

                this.$request({
                    url: '/beidouApi/beidou/psModbus',
                    method: 'get',
                    params: {
                        time: this.psModbusTm,
                        content: this.psModbusInput.replace(/\s/g, "")
                    }
                }).then((res) => {
                    if (res.code === 200) {
                        this.$message({
                            message: '补数完成',
                            type: 'success'
                        });
                    }
                })
            }
        },
        clearMessage(type) {
            if (type === 0) {
                this.modbusInput = ""
            } else {
                this.psModbusInput = ""
            }
        },
    },
}
</script>
<style lang="scss" scoped>
//@import url(); 引入公共css类样式
.page-panel {
    display: flex;
    flex-direction: row;
    height: 100%;
    gap: 10px;
}

.left-card {
    height: 100%;
    flex: 1;
}

.right-card {
    height: 100%;
    flex: 1;
}

.section-title {
    font-size: 20px;
    font-weight: 600;
    color: #2c3e50;
    margin-bottom: 20px;
    display: flex;
    align-items: center;
}

.section-title::before {
    content: '';
    width: 4px;
    height: 20px;
    background: linear-gradient(135deg, #667eea, #2807e2);
    margin-right: 12px;
    border-radius: 2px;
}

.label {
    display: block;
    font-weight: 600;
    color: #2c3e50;
    margin-bottom: 8px;
    font-size: 14px;
}

.control-panel {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 20px;
}
</style>